package com.flute.haflute.web;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Properties;
import java.util.TimeZone;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.flute.haflute.jobbox.common.CloudConstants;
import com.flute.haflute.jobbox.common.CloudContext;

/**
 * 启动JettyServer的web服务
 * 
 * @author Jazz
 */
public class JettyServer {

	private static Logger logger = LoggerFactory.getLogger(JettyServer.class);

	final private static Collection<String> ALL_INTERFACES = Collections
			.unmodifiableList(Arrays.asList(new String[] { "0.0.0.0" }));

	private static String adminUsername;

	private static String adminPassword;

	public static final String ROOT_CONTEXT = "/";

	public static String ADMIN = "admin";

	private static SimpleHttpServer httpServer = null;

	/**
	 * 默认的Web端口.
	 */
	public static final int DEFAULT_PORT = 8080;

	/**
	 * @param args
	 * @throws Exception
	 */
	public static void main(String[] args) throws Exception {
		startJettyServer();

	}

	public static void startJettyServer() throws IOException, Exception {

		TimeZone.setDefault(TimeZone.getTimeZone("GMT+8:00"));

		containerInitialization();

		String adminLoginPassword = System.getProperty(
				CloudConstants.CMD_LINE_ADMIN_PROPERTIES, "admin/admin");

		int port = DEFAULT_PORT;

		try {
			port = Integer.parseInt(System.getProperty(
					CloudConstants.CMD_JETTY_PORT, "8080"));
		} catch (Exception e) {
			logger.error("error when parse " + CloudConstants.CMD_JETTY_PORT
					+ ", use default" + DEFAULT_PORT);
		}

		String log = startEmbeddedWebserver(ALL_INTERFACES, port,
				adminLoginPassword);

		logger.info(log);
	}

	/**
	 * 启动嵌入的Web服务器
	 * 
	 * @param hosts
	 *            主机列表
	 * @param port
	 *            端口
	 * @param adminLoginPassword
	 *            管理员登录密码
	 * @return String
	 * @throws Exception
	 */
	protected static String startEmbeddedWebserver(Collection<String> hosts,
			int port, String adminLoginPassword) throws Exception {

		adminUsername = adminLoginPassword.substring(0,
				adminLoginPassword.indexOf(":"));

		adminPassword = adminLoginPassword.substring(adminLoginPassword
				.indexOf(":") + 1);

		httpServer = new SimpleHttpServer("admin", ROOT_CONTEXT, hosts, port,
				false);

		httpServer.addWebAppContext("/whoami", new File(".").getAbsolutePath());

		final String ROLE = ADMIN;

		httpServer.setAuthentication(ROLE, ROOT_CONTEXT, adminUsername,
				adminPassword, ROLE);

		httpServer.startServer();

		StringBuffer buffer = new StringBuffer();

		for (String host : httpServer.getHosts()) {
			buffer.append("\nWeb console is at: http://");
			buffer.append(host).append(':').append(port);
		}

		buffer.append("\nWeb console login and password: " + adminUsername
				+ "/" + adminPassword);

		return buffer.toString();

	}

	/**
	 * 容器初始化
	 * 
	 * @throws IOException
	 */
	protected static void containerInitialization() throws IOException {
		loadProperties();
	}

	/**
	 * 加载Properties文件
	 * 
	 * @return Properties
	 * @throws IOException
	 */
	protected static Properties loadProperties() throws IOException {

		Properties properties = new Properties();
		properties.load(getPropertiesInputStream());

		for (Enumeration<Object> e = properties.keys(); e.hasMoreElements();) {

			String key = ((String) e.nextElement()).trim();
			String value = properties.getProperty(key).trim();

			copyToSystemProperty(key, value);
		}

		return properties;

	}

	/**
	 * 返回读入的Properties的输入流
	 * 
	 * @return InputStream
	 * @throws IOException
	 */
	protected static InputStream getPropertiesInputStream() throws IOException {

		InputStream inputsteam = new FileInputStream(CloudContext.getRootDir()
				+ CloudConstants.JETTY_PROPERTIES_FILENAME);

		return inputsteam;
	}

	/**
	 * 将读入的Properties属性拷贝到系统的Property中
	 * 
	 * @param key
	 *            系统Property的key
	 * @param value
	 *            系统Property的value
	 */
	protected static void copyToSystemProperty(String key, String value) {
		if (System.getProperty(key) == null
				|| System.getProperty(key).length() == 0) {
			System.setProperty(key, value);
		}
	}

}
